﻿using System.Collections.Generic;
using CfgTable;
using IQIGame.Onigao.GamePlay;
using NetProtocol.POD;


namespace IQIGame.Onigao.Logic
{
    public class LogicItemData
    {
        /// <summary>
        /// 物品唯一Id
        /// </summary>
        public long id { get; private set; }

        /// <summary>
        /// 物品配置
        /// </summary>
        public CfgItem cfg { get; }
        public int cid => cfg.Id;
        /// <summary>
        /// 物品数量
        /// </summary>
        public int num { get; private set; }
        /// <summary>
        /// 物品已使用次数(可能不再有用)
        /// </summary>
        public int usedNum { get; private set; }
        /// <summary>
        /// 创建时间(毫秒)
        /// </summary>
        public long createTime { get; private set; }

        /// <summary>
        /// 物品扩展数据，装备等都使用该引用
        /// </summary>
        public object extData { get; private set; }

        /// <summary>
        /// 装备扩展数据
        /// </summary>
        public EquipmentData equipmentData
        {
            get => extData as EquipmentData;
            set => extData = value;
        }

        /// <summary>
        /// 手持道具扩展数据
        /// </summary>
        public PortableData portableData
        {
            get => extData as PortableData;
            set => extData = value;
        }

        public LogicItemData(long id, CfgItem cfg)
        {
            this.id = id;
            this.cfg = cfg;
            this.num = 1;
            InitExtraData();
        }

        public LogicItemData(ItemPOD itemPOD)
        {
            id = itemPOD.id;
            cfg = TableCenter.item.Get(itemPOD.cid);
            num = 1;
            createTime = itemPOD.createTime;
            InitExtraData();
            SyncData(itemPOD);
        }

        private void InitExtraData()
        {
            switch (cfg.Type)
            {
                case ItemType.Equip:
                    equipmentData = new EquipmentData();
                    break;
                case ItemType.Portable:
                    extData = new PortableData();
                    break;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="itemPOD"></param>
        public void SyncData(ItemPOD itemPOD)
        {
            usedNum = itemPOD.usedNum;
            switch (cfg.Type)
            {
                case ItemType.Equip:
                    equipmentData.SyncData(itemPOD.equipmentData);
                    break;
                case ItemType.Portable:
                    portableData.SyncData(itemPOD.portableData);
                    break;
            }
            // TODO 同步其它数据，尽量保持旧数据对象的引用
        }

        public ItemPOD GeneratePOD()
        {
            ItemPOD itemPOD = new ItemPOD();
            itemPOD.id = id;
            itemPOD.cid = cid;
            itemPOD.usedNum = usedNum;
            itemPOD.createTime = createTime;
            switch (cfg.Type)
            {
                case ItemType.Equip:
                    itemPOD.equipmentData = equipmentData.GeneratePOD();
                    break;
                case ItemType.Portable:
                    itemPOD.portableData = portableData.GeneratePOD();
                    break;
            }
            return itemPOD;
        }

        /// <summary>
        /// 物品是否已过期
        /// </summary>
        public bool IsExpired => false; // TODO

        public static LogicItemData Create(CfgItem cfgItem)
        {
            long id = cfgItem.Type == ItemType.Basic ? cfgItem.Id : LogicHelper.AllocGUID.Invoke();
            LogicItemData itemData = new LogicItemData(id, cfgItem);
            itemData.createTime = LogicHelper.TimeNow;
            return itemData;
        }
    }

    public class PortableData
    {
        /// <summary>
        /// 等级
        /// </summary>
        public int lv { get; set; }
        /// <summary>
        /// 已解锁的部分
        /// </summary>
        public List<int> parts { get; } = new List<int>();
        /// <summary>
        /// 当前正在生效的服务
        /// </summary>
        public HashSet<int> triggeringParts { get; } = new HashSet<int>(4);

        public PortableData()
        {
            lv = 1;
        }

        public PortableData(ItemPortablePOD pod)
        {
            SyncData(pod);
        }

        public void SyncData(ItemPortablePOD pod)
        {
            lv = pod.level;
            parts.Clear();
            parts.AddRange(pod.parts);
        }

        public ItemPortablePOD GeneratePOD()
        {
            ItemPortablePOD pod = new ItemPortablePOD();
            pod.level = lv;
            pod.parts.AddRange(parts);
            return pod;
        }
    }

    public class EquipmentData
    {
        public int lv { get; private set; }
        /// <summary>
        ///  经验
        /// </summary>
        public int exp { get; private set; }
        /// <summary>
        ///  锁定
        /// </summary>
        public bool isLock { get; private set; }
        /// <summary>
        ///  星级
        /// </summary>
        public int star { get; private set; }

        public EquipmentData()
        {
            lv = 0;
            exp = 0;
        }

        public EquipmentData(ItemEquipmentPOD pod)
        {
            SyncData(pod);
        }

        public void SyncData(ItemEquipmentPOD pod)
        {
            lv = pod.level;
            exp = pod.exp;
            isLock = pod.isLock;
            star = pod.star;
        }

        public ItemEquipmentPOD GeneratePOD()
        {
            ItemEquipmentPOD pod = new ItemEquipmentPOD();
            pod.level = lv;
            pod.exp = exp;
            pod.isLock = isLock;
            pod.star = star;
            return pod;
        }
    }
}